home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / libs / unixlib.lha / unix / src / files.c < prev    next >
C/C++ Source or Header  |  1996-10-15  |  3KB  |  115 lines

  1. #include "amiga.h"
  2. #include "files.h"
  3. #include <string.h>
  4.  
  5. /* Unix low-level IO emulation */
  6. /* --------------------------- */
  7.  
  8. /* First, fd definition & allocation */
  9.  
  10. static struct fileinfo **files = NULL;
  11. static int max_files = 0;
  12. #define FILE_STEP 32        /* No of file descriptors to allocate at once */
  13.  
  14. int _get_free_fd(int *nfd, struct fileinfo ***fpt)
  15. {
  16.     register int fd;
  17.     register int i;
  18.     register struct fileinfo *info;
  19.  
  20.     for (fd = 0; fd < max_files && files[fd] != NULL; fd++);
  21.  
  22.     if (fd == max_files) {
  23.     register struct fileinfo **newfiles;
  24.     register struct fileinfo *oldinfo;
  25.     int old_max = max_files;
  26.  
  27.     /* Increase files array by FILE_STEP */
  28.     max_files += FILE_STEP;
  29.     newfiles = malloc(max_files * (sizeof(struct fileinfo *)
  30.                        + sizeof(struct fileinfo)));
  31.     if (!newfiles) {
  32.         errno = ENOMEM;
  33.         return -1;
  34.     }
  35.     info = (struct fileinfo *) &newfiles[max_files];
  36.     if (files) {
  37.         oldinfo = (struct fileinfo *) &files[old_max];
  38.         memcpy(info, oldinfo, old_max * sizeof(struct fileinfo));
  39.     }
  40.     for (i = 0; i < max_files; i++) {
  41.         if (i < old_max)
  42.         newfiles[i] = info + (files[i] - oldinfo);
  43.         else {
  44.         newfiles[i] = NULL;
  45.         info[i].userinfo = 0;
  46.         info[i].count = 0;
  47.         }
  48.     }
  49.     if (files)
  50.         free(files);
  51.     files = newfiles;
  52.     }
  53.     info = (struct fileinfo *) &files[max_files];
  54.     for (i = 0; i < max_files; i++) {
  55.     if (info[i].userinfo == 0) {
  56.         files[fd] = info + i;
  57.         break;
  58.     }
  59.     }
  60.     *nfd = fd;
  61.     *fpt = files;
  62.     return 0;
  63. }
  64.  
  65. int _alloc_fd(void *userinfo, int flags,
  66.           ULONG(*select_start) (void *userinfo, int rd, int wr, int ex),
  67.           int (*select_poll) (void *userinfo, int *rd, int *wr, int *ex),
  68.           int (*read) (void *userinfo, void *buffer, unsigned int length),
  69.           int (*write) (void *userinfo, void *buffer, unsigned int length),
  70.           int (*lseek) (void *userinfo, long rpos, int mode),
  71.           int (*close) (void *userinfo, int internal),
  72.           int (*ioctl) (void *userinfo, int request, void *data))
  73. {
  74.     struct fileinfo **dummy;
  75.     int fd;
  76.  
  77.     if (_get_free_fd(&fd, &dummy) < 0)
  78.     return -1;
  79.  
  80.     files[fd]->userinfo = userinfo;
  81.     files[fd]->flags = flags;
  82.     files[fd]->count = 1;
  83.     files[fd]->select_start = select_start;
  84.     files[fd]->select_poll = select_poll;
  85.     files[fd]->read = read;
  86.     files[fd]->write = write;
  87.     files[fd]->lseek = lseek;
  88.     files[fd]->close = close;
  89.     files[fd]->ioctl = ioctl;
  90.  
  91.     return fd;
  92. }
  93.  
  94. void _free_fd(int fd)
  95. {
  96.     if (0 <= fd && fd < max_files && files[fd] != NULL) {
  97.     if (files[fd]->count == 0 || --files[fd]->count == 0)
  98.         files[fd]->userinfo = 0;
  99.     files[fd] = NULL;
  100.     }
  101. }
  102.  
  103. struct fileinfo *_find_fd(int fd)
  104. {
  105.     if (0 <= fd && fd < max_files && files[fd] != NULL)
  106.     return files[fd];
  107.     errno = EBADF;
  108.     return 0;
  109. }
  110.  
  111. int _last_fd(void)
  112. {
  113.     return max_files;
  114. }
  115.